package tech.bmatch.redpack.service.impl;

import org.apache.commons.lang3.time.DateUtils;
import org.springframework.stereotype.Component;
import tech.bmatch.common.util.DistanceUtil;
import tech.bmatch.common.util.IDUtil;
import tech.bmatch.redpack.model.*;
import tech.bmatch.redpack.param.CreateRedPackParam;
import tech.bmatch.redpack.service.RedPackService;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 红包服务的实现类
 */
@Component
public class RedPackServiceImpl implements RedPackService {
    private static List<RedPack> caches = new ArrayList<>();

    private static Map<String, Merchant> merchantCache = new HashMap<>();

    private static double lon = 120.026208;//目的地经度
    private static double lat = 30.279212;//目的地纬度

    /**
     * 我领取的红包缓存
     */
    private static Map<String, List<MyRedPack>> myRedPackCache = new HashMap();

    static {
        merchantCache.put("test001", new Merchant("test001", "肯德基", "//p1.meituan.net/msmerchant/db00fab658c3661fc92ec793627684cd64503.jpg@275w_156h_1e_1c", 120.021523, 30.275512));
        merchantCache.put("test002", new Merchant("test002", "麦当劳", "//p0.meituan.net/mogu/0a6af6a9acdc84bb26e8fab8d6a250bc111664.png@275w_156h_1e_1c", 120.011091, 30.290126));
        merchantCache.put("test003", new Merchant("test003", "院子餐厅", "//p0.meituan.net/feop/d91337976e8f9540e31caaff3eeffd3c57619.png@275w_156h_1e_1c", 120.04022, 30.28932));
    }

    @Override

    public RedPack create(CreateRedPackParam createRedPackParam) {
        RedPack redPack = null;

        if (createRedPackParam.getCouponType().equals(CouponType.MONEYOFF)) {
            MonenyOffRedPack monenyOffRedPack = new MonenyOffRedPack();
            initRedPack(createRedPackParam, monenyOffRedPack);
            monenyOffRedPack.setTotalAmount(createRedPackParam.getTotalAmount() * 100);
            monenyOffRedPack.setMerchantId(createRedPackParam.getMerchantId());
            redPack = monenyOffRedPack;
        } else {
            redPack = new RedPack();
            initRedPack(createRedPackParam, redPack);
        }

        caches.add(redPack);
        return redPack;
    }

    private void initRedPack(CreateRedPackParam createRedPackParam, RedPack redPack) {
        redPack.setId(IDUtil.getId());
        redPack.setGmtCreated(new Date());
        redPack.setGmtModified(new Date());
        redPack.setCouponType(createRedPackParam.getCouponType());
        redPack.setType(createRedPackParam.getRedPackType());
        redPack.setValidity(createRedPackParam.getValidity());
        redPack.setAmount(createRedPackParam.getAmount() * 100);

        List<RedPackCondition> conditions = new ArrayList<>();
        redPack.setConditions(conditions);

        createRedPackParam.getConditionIds().forEach(id -> {
            RedPackCondition condition = new RedPackCondition();
            condition.setId(id);
            conditions.add(condition);
        });
    }

    @Override
    public List<RedPack> query(RedPackType redPackType) {
        List<RedPack> list = caches.stream().filter(redPack -> redPack.getType().equals(redPackType)).collect(Collectors.toList());

        list.stream().filter(redPack -> redPack.getCouponType().equals(CouponType.MONEYOFF)).forEach(redPack -> {
            MonenyOffRedPack monenyOffRedPack = (MonenyOffRedPack) redPack;
            Merchant merchant = merchantCache.get(monenyOffRedPack.getMerchantId());

            monenyOffRedPack.setLon(merchant.getLon());
            monenyOffRedPack.setLat(merchant.getLat());
            monenyOffRedPack.setMerchantName(merchant.getName());
            monenyOffRedPack.setMerchantLogo(merchant.getLogo());
        });
        return list;
    }

    @Override
    public List<MyRedPack> rainPack(String userId) {
        if (userId == null) {
            return null;
        }

        List<MyRedPack> myRedPackList = myRedPackCache.get(userId);
        if (myRedPackList == null) {
            myRedPackList = new ArrayList<>();
            myRedPackCache.put(userId, myRedPackList);
        }

        long redpackCount = myRedPackList.stream().filter(myRedPack -> DateUtils.isSameDay(new Date(), myRedPack.getGmtCreated())).count();

        if (redpackCount > 0) {
            return null;
        }

        List<RedPack> redPacks = query(RedPackType.VOUCHER);
        List<MyRedPack> result = new ArrayList<>();
        Calendar cal = Calendar.getInstance();
        redPacks.stream().limit(3).forEach(redPack -> {
            MyRedPack myRedPack = new MyRedPack();
            MonenyOffRedPack monenyOffRedPack = (MonenyOffRedPack) redPack;

            myRedPack.setId(IDUtil.getId());
            myRedPack.setGmtModified(new Date());
            myRedPack.setGmtCreated(new Date());
            myRedPack.setUserId(userId);
            myRedPack.setRedPack(redPack);
            myRedPack.setDistance(DistanceUtil.getDistance(lon, lat, monenyOffRedPack.getLon(), monenyOffRedPack.getLat()));

            cal.add(Calendar.DAY_OF_MONTH, redPack.getValidity());
            myRedPack.setValidityDay(cal.getTime());
            cal.clear();
            result.add(myRedPack);
        });
        List list = result.stream().sorted((m1, m2) -> ((Double) m1.getDistance()).intValue() - ((Double) m2.getDistance()).intValue()).collect(Collectors.toList());
        myRedPackList.addAll(list);

        return list;
    }

}
